package com.michael.demos.base.design.builder;

/**
 * 类功能描述:
 * <pre>
 *   建造者模式示例 —— 简化版
 * </pre>
 *
 * @author Michael
 * @version 1.0
 * @date 2020/8/17 10:49
 */
public class BuilderDemo {
	public static void main(String[] args) {
		Car car = new Car.Builder()
				.build();
		System.out.println(car.toString());

		car = car.newBuilder()
				.carBody("奥拓")
				.tyre("奥拓")
				.engine("奥拓")
				.aimingCircle("奥拓")
				.safetyBelt("奥拓")
				.decoration("奥拓")
				.build();
		System.out.println(car.toString());
	}
}

class Car {
	/**
	 * 必需属性
	 */
	//车身
	final String carBody;
	//轮胎
	final String tyre;
	//发动机
	final String engine;
	//方向盘
	final String aimingCircle;
	//安全带
	final String safetyBelt;
	/**
	 * 可选属性
	 */
	//车内装饰品
	final String decoration;

	@Override
	public String toString() {
		return "Car{" +
				"carBody='" + carBody + '\'' +
				", tyre='" + tyre + '\'' +
				", engine='" + engine + '\'' +
				", aimingCircle='" + aimingCircle + '\'' +
				", safetyBelt='" + safetyBelt + '\'' +
				", decoration='" + decoration + '\'' +
				'}';
	}

	/**
	 * car 的构造器 持有 Builder,将builder制造的组件赋值给 car 完成构建
	 *
	 * @param builder
	 */
	public Car(Builder builder) {
		this.carBody = builder.carBody;
		this.tyre = builder.tyre;
		this.engine = builder.engine;
		this.aimingCircle = builder.aimingCircle;
		this.decoration = builder.decoration;
		this.safetyBelt = builder.safetyBelt;
	}

	/**
	 * 重新拿回builder 去改造car
	 *
	 * @return
	 */
	public Builder newBuilder() {
		return new Builder(this);
	}

	public static final class Builder {
		String carBody;
		String tyre;
		String engine;
		String aimingCircle;
		String decoration;
		String safetyBelt;

		public Builder() {
			this.carBody = "宝马";
			this.tyre = "宝马";
			this.engine = "宝马";
			this.aimingCircle = "宝马";
			this.decoration = "宝马";
		}

		/**
		 * 回厂重造
		 *
		 * @param car
		 */
		public Builder(Car car) {
			this.carBody = car.carBody;
			this.safetyBelt = car.safetyBelt;
			this.decoration = car.decoration;
			this.tyre = car.tyre;
			this.aimingCircle = car.aimingCircle;
			this.engine = car.engine;
		}

		/**
		 * 实际属性配置方法
		 *
		 * @param carBody
		 * @return
		 */
		public Builder carBody(String carBody) {
			this.carBody = carBody;
			return this;
		}

		public Builder tyre(String tyre) {
			this.tyre = tyre;
			return this;
		}

		public Builder safetyBelt(String safetyBelt) {
			if (safetyBelt == null) {
				throw new NullPointerException("没系安全带，你开个毛车啊");
			}
			this.safetyBelt = safetyBelt;
			return this;
		}

		public Builder engine(String engine) {
			this.engine = engine;
			return this;
		}

		public Builder aimingCircle(String aimingCircle) {
			this.aimingCircle = aimingCircle;
			return this;
		}

		public Builder decoration(String decoration) {
			this.decoration = decoration;
			return this;
		}

		/**
		 * 最后创造出实体car
		 *
		 * @return
		 */
		public Car build() {
			return new Car(this);
		}
	}
}
